package com.wq.concurrency.aqs;

import java.util.concurrent.*;

/**
 * @Author: wangqiang20995
 * @Date:2019/1/30
 * @Description:
 * @Resource:
 */
public class Pool {

    private static final Integer RESOURCE_CONCURRENCY = 5;

    private static final Integer STEP = 1;

    private  volatile Integer INDEX = 0;//即便这个变量被设置为了volatile保证了内存可见性，但还是不能保证线程安全

    private final Integer ACTUAL_LENGTH ;

    //Semaphore不能保证线程安全，只能保证一个资源被几个线程并发访问，安全控制还是要自己实现
    private Semaphore semaphore;

    public Pool(int concurrency) {
        if (concurrency <= 0) {
            concurrency = RESOURCE_CONCURRENCY;
            ACTUAL_LENGTH = concurrency;
        }else {
            ACTUAL_LENGTH = RESOURCE_CONCURRENCY;
        }

        semaphore = new Semaphore(concurrency);
    }

    public void concurrency(int clients) {
        ExecutorService executorService = new ThreadPoolExecutor(10, 20, 60,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(20));
        for (int i = 0; i < clients; i++) {
            executorService.execute(() -> {
                System.out.println("[" + Thread.currentThread().getName() + "] --> run");

                try {
                    semaphore.acquire(STEP);
                    task();
                    semaphore.release(STEP);
                } catch (InterruptedException e) {
                    System.out.println("[" + Thread.currentThread().getName() + "]中断异常-->" + e.getMessage());
                }
            });
        }

        for (;;) {
            if (semaphore.availablePermits() == ACTUAL_LENGTH) {
                executorService.shutdown();
                break;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("自旋判断Semaphore的坑位是否全部归还异常");
            }
        }

        for (;;) {
            if (executorService.isTerminated()){
                System.out.println("index-->" + INDEX);
                break;
            }

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("主线程判断线程池是否把任务执行完毕出现异常");
            }
        }
    }

    private void task() {
        System.out.println("[" + Thread.currentThread().getName() + "]获取并发访问权限，开始执行task");
        try {
            synchronized (this) {
                INDEX ++;
                System.out.println("["+Thread.currentThread().getName()+"]--index:" + INDEX);
            }
            Thread.sleep(100);

        } catch (InterruptedException e) {
            System.out.println("[" + Thread.currentThread().getName() + "]sleep的中断异常");
        }
    }

    public static void main(String[] args) {
        Pool pool = new Pool(3);
        pool.concurrency(6);
    }
}
